//
// Created by xiaofoo.
//

#ifndef EPICFV_EPICEXTENDCMD_H
#define EPICFV_EPICEXTENDCMD_H

#include <sys/stat.h>
#include <unistd.h>

#include <fstream>
#include <vector>

#include "../util/json.hpp"
#include "EpicCommonCmd.h"
#include "EpicSolverCmd.hpp"

using json_t = nlohmann::json;

class EpicSetModeCmd : public EpicCommonCmd {
 public:
    EpicSetModeCmd(const char *cmdName);

    ~EpicSetModeCmd();

 private:
    void preExec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);

    int exec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);

    void postExec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);
};

class EpicSetDepthCmd : public EpicCommonCmd {
 public:
    EpicSetDepthCmd(const char *cmdName);

    ~EpicSetDepthCmd();

 private:
    void preExec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);

    int exec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);

    void postExec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);
};

class EpicSetWorkerCmd : public EpicCommonCmd {
 public:
    EpicSetWorkerCmd(const char *cmdName);

    ~EpicSetWorkerCmd();

 private:
    void preExec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);

    int exec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);

    void postExec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);
};

class EpicChformalCmd : public EpicCommonCmd {
 public:
    EpicChformalCmd(const char *cmdName);

    ~EpicChformalCmd();

 private:
    void preExec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);

    int exec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);

    void postExec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);
};

class EpicSetEnginesCmd : public EpicCommonCmd {
 public:
    EpicSetEnginesCmd(const char *cmdName);

    ~EpicSetEnginesCmd();

 private:
    void preExec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);

    int exec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);

    void postExec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);
};

class EpicReadFileCmd : public EpicCommonCmd {
 public:
    EpicReadFileCmd(const char *cmdName);

    ~EpicReadFileCmd();

 private:
    void preExec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);

    int exec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);

    void postExec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);

    std::vector<std::string> split_string_by_space(std::string src);

    bool get_macro_value(std::vector<std::string> &macro_value);
};

class EpicCreateClockCmd : public EpicCommonCmd {
 public:
    EpicCreateClockCmd(const char *cmdName);

    ~EpicCreateClockCmd();

 private:
    void preExec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);

    int exec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);

    void postExec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);
};

class EpicCreateRstCmd : public EpicCommonCmd {
 public:
    EpicCreateRstCmd(const char *cmdName);

    ~EpicCreateRstCmd();

 private:
    void preExec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);

    int exec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);

    void postExec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);
};

class EpicRunSimCmd : public EpicCommonCmd {
 public:
    EpicRunSimCmd(const char *cmdName);

    ~EpicRunSimCmd();

 private:
    void preExec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);

    int exec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);

    void postExec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);
};

class EpicCheckFvCmd : public EpicCommonCmd {
 public:
    EpicCheckFvCmd(const char *cmdName);

    ~EpicCheckFvCmd();

 private:
    void preExec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);

    int exec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);

    void postExec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);
};

class EpicExitCmd : public EpicCommonCmd {
 public:
    EpicExitCmd(const char *cmdName);

    ~EpicExitCmd();

 private:
    void preExec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);

    int exec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);

    void postExec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);
};

class EpicQuitCmd : public EpicCommonCmd {
 public:
    EpicQuitCmd(const char *cmdName);

    ~EpicQuitCmd();

 private:
    void preExec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);

    int exec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);

    void postExec(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]);
};

#endif  // EPICFV_EPICEXTENDCMD_H
